package ru.ifmo.sound;

import net.sf.javaml.core.DenseInstance;
import net.sf.javaml.core.Instance;

import java.security.SecureRandom;
import java.util.Random;

/**
 * @author avhaliullin
 */
public class VectorGenerator {
    private static final int n = 128;
    private static final int m = 2048;

    private static final int s = 10;

    public static double randomWeight() {
        return rnd.nextDouble() * 10 - 5;
    }

    public static int getLowerSpectrumSize() {
        return m - m / 2;
    }

    public static int getHigherSpectrumSize() {
        return n - n / 2;
    }

    public static int getCheckedIntervalSeconds() {
        return n / s + 1;
    }

    public static int getShiftBySeconds(WaveFile waveFile, int shiftSeconds) {
        return (int) (waveFile.getAudioFormat().getFrameRate() * shiftSeconds * waveFile.getAudioFormat().getChannels());
    }

    private static double getRate(WaveFile waveFile) {
        double rate = waveFile.getAudioFormat().getFrameRate();
        rate /= s;
        rate /= m;
        return rate;
    }

    private static final Random rnd = new SecureRandom();

    public static Instance generateInstance(WaveFile waveFile) {
        return new DenseInstance(generate(waveFile));
    }

    public static Instance generateInstance(WaveFile waveFile, int shiftSeconds) {
        return new DenseInstance(generate(waveFile, shiftSeconds));
    }

    public static Instance generateInstance(WaveFile waveFile, String className) {
        return new DenseInstance(generate(waveFile), className);
    }

    public static Instance generateInstance(WaveFile waveFile, int shiftSeconds, String className) {
        return new DenseInstance(generate(waveFile, shiftSeconds), className);
    }

    public static double[] generate(WaveFile waveFile) {
        int shift = rnd.nextInt((int) (waveFile.getFramesCount() - getRate(waveFile) * (n + 1) * m));
        return generate(waveFile, shift);
    }

    public static double[] generate(WaveFile waveFile, int shift) {
//        System.out.println(shift);
        double rate = getRate(waveFile);
//        double[] x = new double[n * m];
//        double[] y = new double[n * m];

        double[][] res = new double[n][m];
//        int kk = 0;
        for (int i = 0; i < n; i++) {
            double[] im = new double[m];
            for (int j = 0; j < m; j++) {

                res[i][j] = waveFile.getSampleInt(shift + (int) ((i * m * rate + j * rate) * waveFile.getAudioFormat().getChannels()));
//                x[kk] = kk;
//                y[kk++] = res[i][j];

            }
            Test2.complexToComplex(1, m, res[i], im);
        }

        double[] vector = new double[(n - n / 2) * (m - m / 2)];

        double[] real = new double[n];
        for (int i = m / 2; i < m; i++) {
            double[] im = new double[n];
            for (int j = 0; j < n; j++) {
                real[j] = Math.abs(res[j][i]);
            }
            Test2.complexToComplex(1, n, real, im);
            System.arraycopy(real, n / 2, vector, (i - m / 2) * (n - n / 2), n - n / 2);
        }
        for (int i = 0; i < vector.length; i++) {
            vector[i] = Math.abs(vector[i]);
        }
//
//        Plot2DPanel plotPanel = new Plot2DPanel();
//        plotPanel.addLegend("SOUTH");
//        plotPanel.addLinePlot("Plot", x, y);
//
//        JFrame jFrame = new JFrame();
//        jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//        jFrame.setSize(800, 600);
//        jFrame.add(plotPanel);
//        jFrame.setVisible(true);

        return vector;
    }
}
